﻿using System;
using System.Collections.Generic;
using AutoCAD_CSharp_plug_in3.Chap03;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using static Autodesk.AutoCAD.ApplicationServices.Core.Application;

namespace AutoCAD_CSharp_plug_in3.Chap04
{
    public static class BlockAction
    {
        private const string BlockNamePrefix = "Chap04_";

        public static void ImportBlock()
        {
            var doc = DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    using (DocumentManager.MdiActiveDocument.LockDocument())
                    {
                        // 集流管段系列  
                        NewMethod2(Block1.CreateAll(BlockNamePrefix), db);

                        // 弯管系列-主视  
                        NewMethod2(Block2.CreateAll(BlockNamePrefix), db);

                        // 弯管圆整-Z  
                        NewMethod2(Block3.CreateAll(BlockNamePrefix), db);

                        // 法兰PN40系列-主视 
                        NewMethod2(Block4.CreateAll(BlockNamePrefix), db);

                        // 法兰PN40圆整-Z
                        NewMethod2(Block5.CreateAll(BlockNamePrefix), db);
                    }

                    tr.Commit();
                    ed.WriteMessage("\n========== 批量导入块参照 ==========");
                }
                catch (Exception ex)
                {
                    tr.Abort();
                    ed.WriteMessage($"\n导入块发生错误: {ex.Message}");
                }
            }
        }

        private static void NewMethod2(List<BlockTableRecord> r1, Database db)
        {
            foreach (var rcd in r1)
            {
                var blockName = rcd.Name;
                db.CurrentSpaceId.InsertBlockReference(
                    blockName,
                    Point3d.Origin,
                    new Scale3d(1.0),
                    0.0,
                    "0",
                    blockName,
                    rcd);
            }
        }

        public static void RemoveBlock()
        {
            var doc = DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    NewMethod(tr, db);
                    NewMethod1(tr, db);
                    tr.Commit();
                    ed.WriteMessage("\n========== 批量删除块参照 ==========");
                }
                catch (Exception ex)
                {
                    tr.Abort();
                    ed.WriteMessage($"\n删除块定义发生错误: {ex.Message}");
                }
            }
        }

        private static void NewMethod1(Transaction tr, Database db)
        {
            var btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

            foreach (var objId in btr)
            {
                var entity = tr.GetObject(objId, OpenMode.ForRead);

                if (entity is BlockReference blockRef)
                {
                    var blockDef = (BlockTableRecord)tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead);

                    if (blockDef.Name.StartsWith(BlockNamePrefix, StringComparison.OrdinalIgnoreCase))
                    {
                        entity.UpgradeOpen();
                        entity.Erase();
                    }
                }
            }
        }

        private static void NewMethod(Transaction tr, Database db)
        {
            var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);

            var blocksToRemove = new List<ObjectId>();

            foreach (var btrId in bt)
            {
                var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);


                if (btr.Name.StartsWith(BlockNamePrefix, StringComparison.OrdinalIgnoreCase))
                {
                    if (btr.IsLayout || btr.IsDependent || btr.IsFromExternalReference ||
                        btr.IsFromOverlayReference)
                        continue;

                    blocksToRemove.Add(btrId);
                }
            }

            if (blocksToRemove.Count > 0)
                foreach (var blockId in blocksToRemove)
                {
                    var btr = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForWrite);
                    btr.Erase(true);
                }
        }
    }
}